<!--/****⽣成⽇期: 2024-03-04 10:15:42****/-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <title>吕文宝的页面</title>
  </head>

  <body>
    <input type="text" class="input" value="123" />
  </body>
</html>
<script>
  // let input = document.querySelector("input");

  // console.log(Number(input.value).toLocaleString("zh-Hans-CN-u-nu-hanidec"));
  // / let const var 定义变量常量
  // 作用域:
  // 全局作用域:最外层的
  // 局部作用/函数级作用域:定义在函数内部的,在在函数里面起作用
  // 块级作用域:通过let/const 定义在代码块(if for中),只在代码块里面起作用
  //   let count 没有变量提升 ,前面叫暂时性死区,是块级作用域   var 是函数级 / 全局作用域

  //   var 全局作用域;
  //   var num = 1;
  //   function test() {
  //     console.log(num);
  //   }
  //   test();
  //   函数级作用域(只在函数内部起作用);
  //   function test() {
  //     if (true) {
  //       var num = 1;
  //     }
  //     console.log("函数内部", num);
  //   }
  //   test();
  //   console.log("函数外", num);
  //   //   块级作用域:
  //   function test() {
  //     if (true) {
  //       let num = 1;
  //     }
  //     console.log("函数内部", num);
  //   }
  //   test();
  //   console.log("函数外", num);

  //   var num = 1;
  //   function test() {
  //     var num = 5;
  //     if (true) {
  //       console.log(num); //就近作用域取值,最近的取不到就到外层作用域去取,这个取值的过程。就是作用域链
  //     }
  //   }
  //   test();

  //   let count 没有变量提升 ,前面叫暂时性死区,是块级作用域   var 是函数级 / 全局作用域
  //   console.log(num);
  //   var num = 1;
  //   function test() {
  //     console.log(num); //undefined  变量提升是提升到当前作用域的最顶上;
  //     var num = 5;
  //     if (true) {
  //       console.log(num); // 暂时性死区报错
  //       let num = 3;
  //     }
  //   }
  //   test();

  //   const检测的是内存地址的变换,定义常量的时候必须赋值,且无法修改
  //   const实际上保证的，并不是变量的值不得改动，而是变量指向的那个内存地址不得改动。
  //   对于简单类型的数据（数值、字符串、布尔值），值就保存在变量指向的那个内存地址，因此等同于常量。
  // const flag = false;
  // const obj = { name: "张三" };
  //   flag = true;  // 报错,因为普通数据类型的值就保存在变量指向的那个内存地址,所以修改数据就是修改内存地址
  // obj.name = "李四";
  // 不报错,因为const检测的只是内存地址的变换,
  //   引用数据类型是在堆内存中存储的,修改相当于在堆内存中的内容发生变化,但指针指向不变.
  //   只要指针指向不变就不会报错;
  //   扩展:
  //   基本类型
  //         占用空间固定，保存在栈中
  //         保存与复制的是值本身
  //         可以使用typeof检测数据的类型
  //   引用类型
  //         占用空间不固定，保存在堆中
  //         保存与复制的是指向对象的一个指针（浅拷贝）
  //         使用instanceof检测数据类型
  //         使用new()方法构造出的对象是引用型

  //   ==========解构赋值==============
  //   数组解构:根据下标对应关系
  //   对象解构 :根据key值对应关系
  //   函数参数结构

  //   let [a, b, [c], [d, [e]]] = [1, 2, 3, [4, [5]]];
  //   c没有值;
  //   let { a, b, c } = { a: 20, b: 30, c: 40 }; // a:20  b:30   c:40
  // let { a: b, c: d, e: f } = { a: 20, b: 30, c: 40 };
  //   a  未定义,报错
  //   b  20
  //   c  未定义,报错
  //   d  40
  //   e  未定义,报错
  //   f  undefined

  // ================ 箭头函数 =================
  // 普通函数 : this指向调用时,谁调用他就指向谁,可以改变 call/apply
  // 箭头函数 : this指向定义时候外层作用域上下文  不可改变

  // call、apply、bind 用于改变this指向  第一个参数都是this指向
  // bind  返回的是一个函数,需要手动执行一下,参数用逗号分隔
  // call  传入的参数用逗号分隔
  // apply 传入的参数是一个数组  apply  是a开头的  Array

  // ================ 数组拓展 ==================
  // Array.from 将类数组对象,转换成数组对象
  // var arr = [1, 2, 2, 2, 3, 3, 6, null, null, undefined, undefined];
  // console.log(Array.from(new Set(arr)));
  // console.log([...new Set(arr)]);

  // Array.find()用于找出第一个符合条件的数组成员。它的参数是一个回调函数
  // Array.findIndex()回第一个符合条件的数组成员的位置，如果所有成员都不符合条件，则返回-1。
  // ES2022 新增了两个方法findLast()和findLastIndex()，
  // 从数组的最后一个成员开始，依次向前检查，其他都保持不变。
  // let arr = [1, 2, 2, 3, 4, 5];
  // console.log(
  //   arr.find(() => {
  //     return 2;
  //   })
  // );
  // Array.fill() 方法使用给定值，填充一个数组。数组中已有的元素，会被全部抹去。
  // fill方法还可以接受第二个和第三个参数，用于指定填充的起始位置和结束位置
  // 如果填充的类型为对象，那么被赋值的是同一个内存地址的对象，而不是深拷贝对象。
  //asdfasdfsdffg
  // let str = "asdfasdfsdffg";

  // let arr = str.split("");
  // console.log(arr);
  // function arrReduce(arr) {
  //   let newObj = {};
  //   for (let i = 0; i < arr.length; i++) {
  //     let cur = arr[i];
  //     if (!newObj[cur]) {
  //       newObj[cur] = 0;
  //     }
  //     newObj[cur]++;
  //   }
  //   return newObj;
  // }

  // console.log(arrReduce(arr));

  // ============== promise ==============
  // 异步编程的解决方式，以前的时候都是回调函数的方式(回调地狱)
  // 三种状态: 进行中 已成功 已失败
  // 只能出现两种结果: 成功(resolve)then    失败(reject)catch
  // then 和catch回调函数,都会返回一个新的promise实例,所以可以往后链式调用
  // 后面的catch会捕获前面所有的为捕获的错误
  // 如果没有catch 错误不会影响外层,除非早下一个事件循环里面
  // 不要在.then中写两个回调函数,因为第二个回调函数捕获不到第一个回调里面的错误,直接catch就能捕获

  // new Promise((resolve, reject) => {
  //   reject(); // 失败
  //   resolve(111); // 成功
  // })
  //   .then((res) => {
  //     // 成功的回调
  //     console.log(res, "then");
  //   })
  //   .catch((err) => {
  //     // 失败的回调
  //     console.log(err, "err");
  //   })
  //   .finally((res) => {
  //     // 成功 / 失败都走的回调
  //     console.log(res, "finally");
  //   });

  //  all方法  race方法  any方法都会返回一个新的promise实例
  // let p1 = new Promise((resolve, reject) => {
  //   resolve(111);
  // })
  //   .then((res) => {
  //     console.log(res);
  //   })
  //   .catch((err) => {
  //     console.log(err);
  //   });
  // let p2 = new Promise((resolve, reject) => {
  //   resolve(222);
  // })
  //   .then((res) => {
  //     console.log(res);
  //   })
  //   .catch((err) => {
  //     console.log(err);
  //   });

  // // all方法,是执行多个promise实例,所有实例都成功,返回的实例就是成功,并把参数放到一个数组中传入新实例对象  有一个失败就会失败
  // Promise.all([p1, p2])
  //   .then((res) => {
  //     // 成功的回调
  //     console.log(res, "all");
  //   })
  //   .catch((err) => {
  //     // 失败的回调
  //     console.log(err, "all");
  //   });

  // // any方法,是执行多个promise实例,所有实例都失败才是失败,只要有一个实例状态成功,新实例状态就是成功
  // Promise.any([p1, p2])
  //   .then((res) => {
  //     // 成功的回调
  //     console.log(res, "any");
  //   })
  //   .catch((err) => {
  //     // 失败的回调
  //     console.log(err, "any");
  //   });

  // // race方法,跑的意思,是执行多个promise实例,只和第一个的状态有关,第一个执行完的实例成功,新实例状态就是成功,第一个失败就是失败
  // Promise.race([p1, p2])
  //   .then((res) => {
  //     // 成功的回调
  //     console.log(res, "race");
  //   })
  //   .catch((err) => {
  //     // 失败的回调
  //     console.log(err, "race");
  //   });

  // // allSettled方法,是执行多个promise实例,但是只返回成功状态的回调,会把每一个实例状态的成功或者失败,放到一个对象中传入then函数里面
  // Promise.allSettled([p1, p2]).then((res) => {
  //   // 成功的回调
  //   console.log(res, "allSettled");
  // });

  // 用 || 默认取值,可能会因为隐式转换,得到的不是自己想要的

  // ================ Set && Map ==============
  // Set是Es6的新增的数据结构,他的成员是唯一的.我一般用它来进行数组去重,他也有一些自己的方法 add delete has  size  clear
  // WeakSet 里面只能是对象,里面的对象是弱引用关系,也会被垃圾回收机制回收

  // Map结构 作用和对象差不多. key值可以是任意类型;里面有一些自己的方法
  // 可以用它做一些映射关系,数据量大的时候, 性能会好一些
  // 里面有一个weakMap  它的key值只能是对象,也是弱引用关系

  // async await 是generator的语法糖   里面是一个generator的自执行函数
  // ========= module语法 ===========
  // es6的导入导出 export 抛出多个   import {名字不变} from...
  // export default 只能抛出一个     import 名字 from ...
  // 还有一种导入是 import* as 名字(自己定义) from ...
  // 使用时用名字.方法名(抛出时的方法名)
  // git config --global  user.name "git仓库用户名"
  // git config --global user.email "邮箱"
  // mkdir
</script>
